package com.ww.springboot.boot.utils;

import cn.hutool.core.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.MediaType;

import javax.net.ssl.*;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 描述：
 *
 * @author wanwei
 * @since 2021-06-10 16:16
 */
@Slf4j
public class YouZhengPostUtil {

	public static final List<String> DELIVERY = Arrays.asList("/static/certs/youzheng.p12", "5mggUkaL", "/static/certs/cacerts");
	public static final List<String> FEIYOU = Arrays.asList("/static/certs/cbip210025.p12", "V0JkT82i", "/static/certs/cacerts");

	public static String postXml(String url, String req, List<String> certList) {
		return post(url, req, certList, MediaType.TEXT_XML_VALUE, new HashMap<>());
	}

	public static String postJson(String url, String req, List<String> certList, Map<String, String> header) {
		return post(url, req, certList, MediaType.APPLICATION_JSON_VALUE, header);
	}

	private static String post(String url, String req, List<String> certList,
							   String mediaType, Map<String, String> header) {
		InputStream inputStream = null;
		HttpsURLConnection con = null;
		try {
			HttpsURLConnection.setDefaultSSLSocketFactory(addCert(certList).getSocketFactory());
			URL url1 = new URL(url);
			con = (HttpsURLConnection) url1.openConnection();
			if (ObjectUtil.isNotEmpty(header)) {
				for (Map.Entry<String, String> map : header.entrySet()) {
					con.setRequestProperty(map.getKey(), map.getValue());
				}
			}
			con.setRequestMethod("POST");
			con.setRequestProperty("Content-Type", mediaType);
			con.setInstanceFollowRedirects(false);
			con.setDoOutput(true);
			con.setDoInput(true);
			con.connect();
			OutputStreamWriter out = new OutputStreamWriter(con.getOutputStream(), "UTF-8");
			out.write(req);
			out.flush();
			out.close();
			inputStream = con.getInputStream();
			return inputStreamToString(inputStream);
		} catch (Exception e) {
			log.error("接口请求失败：", e);
			throw new RuntimeException("接口请求失败：" + e.getMessage());
		} finally {
			if (inputStream != null) {
				try {
					inputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (con != null) {
				con.disconnect();
			}
		}
	}

	public static String inputStreamToString(InputStream is) throws IOException {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		int i = -1;
		while ((i = is.read()) != -1) {
			baos.write(i);
		}
		return baos.toString();
	}

	private static SSLContext addCert(List<String> certList) {
		try {
			KeyStore clientStore = KeyStore.getInstance("PKCS12");

			ClassPathResource classPathResource = new ClassPathResource(certList.get(0));
			//p12证书全路径，证书密码
			clientStore.load(classPathResource.getInputStream(), certList.get(1).toCharArray());
			KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
			//证书密码
			kmf.init(clientStore, certList.get(1).toCharArray());
			KeyManager[] kms = kmf.getKeyManagers();
			KeyStore trustStore = KeyStore.getInstance("JKS");
			ClassPathResource cacerts = new ClassPathResource(certList.get(2));
			//jdk证书库全路径
			trustStore.load(cacerts.getInputStream(), "changeit".toCharArray());
			TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
			tmf.init(trustStore);
			TrustManager[] tms = tmf.getTrustManagers();
			SSLContext sslContext = null;
			sslContext = SSLContext.getInstance("TLS");
			sslContext.init(kms, tms, new SecureRandom());
			return sslContext;
		} catch (Exception e) {
			log.error("邮政证书添加失败!", e);
			throw new RuntimeException("邮政证书添加失败：" + e.getMessage());
		}
	}
}
